package com.hkts.naturalgas.curvesettings.service.serviceimpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hkts.naturalgas.curvesettings.entity.Curve;
import com.hkts.naturalgas.curvesettings.entity.CurveSettings;
import com.hkts.naturalgas.curvesettings.entity.CurveState;
import com.hkts.naturalgas.curvesettings.entity.HktsCycleTime;
import com.hkts.naturalgas.curvesettings.mapper.CurveMapper;
import com.hkts.naturalgas.curvesettings.mapper.CurveSettingsMapper;
import com.hkts.naturalgas.curvesettings.mapper.CurveStateMapper;
import com.hkts.naturalgas.curvesettings.mapper.HktsCycleTimeMapper;
import com.hkts.naturalgas.curvesettings.service.ICurveSettingsService;
import com.hkts.naturalgas.curvesettings.vo.CurveVo;
import com.hkts.naturalgas.datahandler.configurationfile.CurveConfig;
import com.hkts.naturalgas.datahandler.constance.EnviromentConstance;
import com.hkts.naturalgas.datahandler.constance.EnviromentCurveStateConstance;
import com.hkts.naturalgas.dictionaries.entity.HktsEnvironmentProtectionDictionaries;
import com.hkts.naturalgas.utils.Result;
import com.hkts.naturalgas.utils.ResultUtil;
import com.hkts.naturalgas.utils.SnowFlakeUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yck
 * @since 2021-10-11
 */
@Service
@Transactional
public class CurveSettingsServiceImpl extends ServiceImpl<CurveSettingsMapper, CurveSettings> implements ICurveSettingsService {


    @Autowired
    private CurveSettingsMapper curveSettingsMapper;
    @Autowired
    private CurveMapper curveMapper;
    @Autowired
    public ICurveSettingsService iCurveSettingsService;

    @Autowired
    private HktsCycleTimeMapper hktsCycleTimeMapper;
    @Autowired
    private CurveStateMapper curveStateMapper;
    @Override
    public IPage<CurveSettings> selectPage(Page<CurveSettings> page, CurveSettings curveSettings) {
        QueryWrapper<CurveSettings> query = Wrappers.query();
        QueryWrapper<CurveSettings> entityWrapper = getEntityWrapper(query, curveSettings);
        return curveSettingsMapper.selectPage(page, entityWrapper);
    }


    @Override
    public List<CurveSettings> selectList(CurveSettings curveSettings) {
        QueryWrapper<CurveSettings> query = Wrappers.query();
        QueryWrapper<CurveSettings> entityWrapper = getEntityWrapper(query, curveSettings);
        return curveSettingsMapper.selectList(entityWrapper);
    }

    @Override
    public List<CurveSettings> selectListforShelder(CurveSettings curveSettings) {
        QueryWrapper<CurveSettings> query = Wrappers.query();
        query.lambda().eq(CurveSettings::getCurveId, curveSettings.getCurveId());
        query.lambda().orderByAsc(CurveSettings::getOrderBy);
        List<CurveSettings> curveSettings1 = curveSettingsMapper.selectList(query);
        return curveSettings1;
    }

    @Override
    public Map<String, List<CurveSettings>> selectMapforShelder(List<HktsEnvironmentProtectionDictionaries> hktsEnvironmentProtectionDictionaries1) {
        Map<String, List<CurveSettings>> map = new HashMap<String, List<CurveSettings>>();
        QueryWrapper<CurveSettings> query = Wrappers.query();
        query.lambda().orderByAsc(CurveSettings::getOrderBy);
        List<CurveSettings> curveSettings1 = curveSettingsMapper.selectList(query);
        for (int i = 0; i < hktsEnvironmentProtectionDictionaries1.size(); i++) {
            HktsEnvironmentProtectionDictionaries hktsEnvironmentProtectionDictionaries = hktsEnvironmentProtectionDictionaries1.get(i);
            if (StringUtils.isNotBlank(hktsEnvironmentProtectionDictionaries.getCurveId())) {
                map.put(hktsEnvironmentProtectionDictionaries.getCurveId(), curveSettings1.stream().filter(curveSetting ->
                        hktsEnvironmentProtectionDictionaries.getCurveId().equals(curveSetting.getCurveId())).collect(Collectors.toList()));
            }
        }
        return map;
    }

    /**
     * 公共查询条件
     *
     * @param entityWrapper
     * @return
     */
    public QueryWrapper<CurveSettings> getEntityWrapper(QueryWrapper<CurveSettings> entityWrapper, CurveSettings curveSettings) {
        //条件拼接
        if (StringUtils.isNotBlank(curveSettings.getWorkShop())) {
            entityWrapper.like(CurveSettings.WORK_SHOP, curveSettings.getWorkShop());
        }
        if (StringUtils.isNotBlank(curveSettings.getFlameSystem())) {
            entityWrapper.like(CurveSettings.FLAME_SYSTEM, curveSettings.getFlameSystem());
        }

        if (StringUtils.isNotBlank(curveSettings.getCurrentNode())) {
            entityWrapper.like(CurveSettings.CURRENT_NODE, curveSettings.getCurrentNode());
        }

        if (StringUtils.isNotBlank(curveSettings.getType())) {
            entityWrapper.like(CurveSettings.TYPE, curveSettings.getType());
        }

        return entityWrapper;
    }

    public Map<String, Object> getCurveData(String curveId) {
        QueryWrapper<CurveSettings> query = Wrappers.query();
        query.lambda().eq(CurveSettings::getCurveId, curveId);
        query.lambda().ne(CurveSettings::getIsHidden, 1);
        query.lambda().orderByAsc(CurveSettings::getTimePoint);
        List<CurveSettings> curveSettings = curveSettingsMapper.selectList(query);
        Curve curve = curveMapper.selectById(curveId);
        List<Map<String, Object>> resultMap = new ArrayList<>();
        for (int i = 0; i < curveSettings.size(); i++) {
            Map<String, Object> curveMap = new HashMap<>();
            curveMap.put("id", curveSettings.get(i).getId());
            curveMap.put("hour", curveSettings.get(i).getTimePoint());
            curveMap.put("temperature", curveSettings.get(i).getTemperature());
            curveMap.put("rate", curveSettings.get(i).getRateHour());
            curveMap.put("curveId", curveSettings.get(i).getCurveId());
            resultMap.add(curveMap);
        }
        int size = 10 - resultMap.size();
        if (size > 0) {
            for (int i = 0; i < size; i++) {
                Map<String, Object> curveMap = new HashMap<>();
                curveMap.put("id", "");
                curveMap.put("hour", 0);
                curveMap.put("temperature", 0);
                curveMap.put("rate", 0);
                curveMap.put("curveId", "");
                resultMap.add(curveMap);
            }
        }
        Map<String, Object> curveData = new HashMap<>();
        curveData.put("curveId", curve.getId());
        curveData.put("curveName", curve.getCurveName());
        curveData.put("curveHeatNumber", curve.getHeatNumber());
        curveData.put("flameSystem", curve.getFlameSystem());
        curveData.put("workShop", curve.getWorkShopId());
        curveData.put("data", resultMap);

        QueryWrapper<CurveSettings> curveSettingsQueryWrapper = Wrappers.query();
        curveSettingsQueryWrapper.lambda().eq(CurveSettings::getCurveId, curve.getId());
        List<CurveSettings> curveSettingsById = curveSettingsMapper.selectList(curveSettingsQueryWrapper);
        QueryWrapper<CurveSettings> curveSettingsQuery = Wrappers.query();
        curveSettingsQuery.lambda().eq(CurveSettings::getCurveId, curve.getId()).eq(CurveSettings::getCurrentNode, 1);
        CurveSettings curveSettingsByCurrentNode = curveSettingsMapper.selectOne(curveSettingsQuery);

        Integer runTime = 0;


        for (int i = 0; i < curveSettingsById.size(); i++) {
            if (curveSettingsById.get(i).getOrderBy() < curveSettingsByCurrentNode.getOrderBy()) {
                runTime = curveSettingsById.get(i).getTotalSeconds() + runTime;
            }
        }

        double runTimeT = new BigDecimal((float) (runTime + curveSettingsByCurrentNode.getCurrentSeconds()) / 3600).setScale(5, BigDecimal.ROUND_HALF_UP).doubleValue();
        curveData.put("runTime", runTimeT);

        return curveData;
    }

    @Override
    public Result<Object> updateCurve(CurveVo curveVos) {
        QueryWrapper<CurveState> queryCurveState = Wrappers.query();
        queryCurveState.lambda().eq(CurveState::getWorkShopId,curveVos.getWorkShop());
        CurveState curveState = curveStateMapper.selectOne(queryCurveState);
        if(!curveState.getSystemCurveState().equals(EnviromentCurveStateConstance.SHUT_DOWN)){
         return    ResultUtil.error("请停止系统后再重新点击生效按钮！");
        }
        DecimalFormat df = new DecimalFormat("0.0000");
        Curve curve = curveMapper.selectById(curveVos.getCurveId());
        for (int i = 0; i < curveVos.getData().size(); i++) {
            if (StringUtils.isNotBlank(curveVos.getData().get(i).getId())&&curveVos.getData().get(i).getTemperature()!=0) {
                CurveSettings curveSettings = curveSettingsMapper.selectById(curveVos.getData().get(i).getId().toString());
                curveSettings.setTimePoint(curveVos.getData().get(i).getHour());
                curveSettings.setRateHour(curveVos.getData().get(i).getRate());
                curveSettings.setTemperature(curveVos.getData().get(i).getTemperature());
                curveSettings.setCurrentSeconds(0);
                curveSettings.setOrderBy(i+1);
                //设置总时间
                if(curveVos.getData().get(i+1).getHour()==0){
                    curveSettings.setTotalSeconds(0);
                }else{
                 int totalSeconds= (int)(3600* (curveVos.getData().get(i+1).getHour()-curveVos.getData().get(i).getHour()));
                    curveSettings.setTotalSeconds(totalSeconds);
                }
                if (curveSettings.getRateHour() == -1) {
                    curveSettings.setCurrentNode("1");
                } else {
                    curveSettings.setCurrentNode("0");
                }
                curveSettingsMapper.updateById(curveSettings);

            } else if (curveVos.getData().get(i).getHour()== 0 && curveVos.getData().get(i).getTemperature()== 0 && StringUtils.isNotBlank(curveVos.getData().get(i).getId())) {
                curveSettingsMapper.deleteById(curveVos.getData().get(i).getId());
            } else if (Math.abs(curveVos.getData().get(i).getHour()) > 0.001 && StringUtils.isBlank(curveVos.getData().get(i).getId())) {
                CurveSettings curveSettings = new CurveSettings();
                String id = String.valueOf(SnowFlakeUtil.getFlowIdInstance().nextId());
                curveSettings.setId(id);
                curveSettings.setCurveId(curveVos.getCurveId());
                curveSettings.setCurrentNode("0");
                curveSettings.setCurrentSeconds(0);
                curveSettings.setType(curve.getType());
                curveSettings.setFlameSystem(curve.getFlameSystem());
                /*String format = df.format(curveVos.getData().get(i).getRate() / 3600);
                float rateSeconds = Float.parseFloat(format);
                curveSettings.setRateSeconds(rateSeconds);*/
                curveSettings.setRateHour(curveVos.getData().get(i).getRate());
                curveSettings.setTimePoint(curveVos.getData().get(i).getHour());
                curveSettings.setFlameSystem(curveVos.getFlameSystem());
                curveSettings.setTemperature(curveVos.getData().get(i).getTemperature());
                curveSettings.setOrderBy(i+1);
                //设置总时间
                if(curveVos.getData().get(i+1).getHour()==0){
                    curveSettings.setTotalSeconds(0);
                }else{
                    curveSettings.setTotalSeconds((int)(3600* (curveVos.getData().get(i+1).getHour()-curveVos.getData().get(i).getHour())));
                }
                curveSettings.setWorkShop(curveVos.getWorkShop());
                QueryWrapper<CurveSettings> query = Wrappers.query();
                query.lambda().ne(CurveSettings::getId, "");
                Integer integer = curveSettingsMapper.selectCount(query);
                curveSettings.setOrderBy(integer + 1);
                curveSettingsMapper.insert(curveSettings);
            }
        }
        QueryWrapper<CurveSettings> query = Wrappers.query();
        query.lambda().eq(CurveSettings::getCurveId, curveVos.getCurveId());
        query.lambda().ne(CurveSettings::getIsHidden, 1);
        query.lambda().orderByAsc(CurveSettings::getOrderBy);
        List<CurveSettings> curveSettings = curveSettingsMapper.selectList(query);
        int orderBy=0;
        for (int i = 0; i < curveSettings.size(); i++) {
            if(curveSettings.get(i).getOrderBy()>orderBy){
                orderBy=curveSettings.get(i).getOrderBy();
            }
            if (Math.abs(curveSettings.get(i).getTemperature()) > 0.001 && i != 0) {
                Float temperature = curveSettings.get(i).getTemperature();
                Float temperatureTop = curveSettings.get(i - 1).getTemperature();
                BigDecimal b1 = new BigDecimal(Float.toString(temperature));
                BigDecimal b2 = new BigDecimal(Float.toString(temperatureTop));
                float ss = b1.subtract(b2).floatValue();
                if (Math.abs(ss) < 0.001){
                    CurveSettings curveSettingsT = curveSettings.get(i - 1);
                    curveSettingsT.setRateSeconds(0.00f);
                    curveSettingsMapper.updateById(curveSettingsT);
                }else {
                    float rateSeconds =ss / curveSettings.get(i-1).getTotalSeconds();
                    CurveSettings curveSettingsT = curveSettings.get(i - 1);
                    curveSettingsT.setRateSeconds(rateSeconds);
                    curveSettingsMapper.updateById(curveSettingsT);
                }

            }
        }
        /** 功能描述:
        *[curveVos]
        */
        QueryWrapper<CurveSettings> queryhidden = Wrappers.query();
        queryhidden.lambda().eq(CurveSettings::getCurveId, curveVos.getCurveId());
        queryhidden.lambda().eq(CurveSettings::getIsHidden, 1);
        queryhidden.lambda().orderByAsc(CurveSettings::getOrderBy);
        CurveSettings curveSettings1 = curveSettingsMapper.selectOne(queryhidden);
        curveSettings1.setOrderBy(orderBy+1);
        curveSettingsMapper.updateById(curveSettings1);
        // this.updateBatchById(curveSettings);
        //





        if (curve.getType().equals(EnviromentConstance.IS_RS)) {
            //计算周期时间
            Float toatalHour = 0f;
            for (int i = 0; i < curveVos.getData().size(); i++) {
                if(toatalHour<=curveVos.getData().get(i).getHour()){
                    toatalHour=curveVos.getData().get(i).getHour();
                }
            }
            QueryWrapper<HktsCycleTime> queryHktsCycleTime=new QueryWrapper<HktsCycleTime>();
            queryHktsCycleTime.lambda().eq(HktsCycleTime::getWorkShopId,curveVos.getWorkShop());
            HktsCycleTime hktsCycleTime = hktsCycleTimeMapper.selectOne(queryHktsCycleTime);
            hktsCycleTime.setCycleTime(toatalHour/3);
            hktsCycleTimeMapper.updateById(hktsCycleTime);
            //计算起始节点位置
            QueryWrapper<Curve> queryCurve = Wrappers.query();
            queryCurve.lambda().eq(Curve::getWorkShopId, curveVos.getWorkShop());
            queryCurve.lambda().eq(Curve::getType, EnviromentConstance.IS_RS);
            queryCurve.lambda().orderByAsc(Curve::getFlameSystem);
            queryCurve.lambda().orderByAsc(Curve::getOrderBy);
            List<Curve> curves = curveMapper.selectList(queryCurve);
            for (int j = 0; j < curves.size(); j++) {
                if(!curves.get(j).getId().equals(curve.getId())){
                    continue;
                }
                CurveSettings ve = new CurveSettings();
                ve.setCurveId(curves.get(j).getId());
                List<CurveSettings> curveSettingList = iCurveSettingsService.selectListforShelder(ve);
                Integer totalSeconds = 0;
                boolean index1 = false;
                boolean index2 = false;
                for (int g = 0; g < curveSettings.size(); g++) {
                    totalSeconds = totalSeconds + curveSettingList.get(g).getTotalSeconds();
                    if (j % 3 == 0) {
                        if (g == 0) {
                            curveSettingList.get(g).setCurrentSeconds(0);
                            curveSettingList.get(g).setCurrentNode("1");
                        } else {
                            curveSettingList.get(g).setCurrentNode("0");
                            curveSettingList.get(g).setCurrentSeconds(0);
                        }
                    } else if (j % 3 == 1) {
                        if (index1 == false && totalSeconds >= hktsCycleTime.getCycleTime() * 3600) {
                            Float time = hktsCycleTime.getCycleTime() * 3600;
                            curveSettingList.get(g).setCurrentSeconds(curveSettings.get(g).getTotalSeconds() - (totalSeconds - time.intValue()));
                            curveSettingList.get(g).setCurrentNode("1");
                            index1 = true;
                        } else {
                            curveSettingList.get(g).setCurrentSeconds(0);
                            curveSettingList.get(g).setCurrentNode("0");
                        }
                    } else if (j % 3 == 2) {
                        if (index2 == false && totalSeconds >= hktsCycleTime.getCycleTime() * 3600 * 2) {
                            Float time = hktsCycleTime.getCycleTime() * 3600 * 2;
                            curveSettingList.get(g).setCurrentSeconds(curveSettings.get(g).getTotalSeconds() - (totalSeconds - time.intValue()));
                            curveSettingList.get(g).setCurrentNode("1");
                            index2 = true;
                        } else {
                            curveSettingList.get(g).setCurrentSeconds(0);
                            curveSettingList.get(g).setCurrentNode("0");
                        }
                    }
                }
                iCurveSettingsService.updateBatchById(curveSettingList);
            }
        }else{
            Float toatalHour = 0f;
            for (int i = 0; i < curveVos.getData().size(); i++) {
                if(toatalHour<=curveVos.getData().get(i).getHour()){
                    toatalHour=curveVos.getData().get(i).getHour();
                }
            }
            QueryWrapper<HktsCycleTime> queryHktsCycleTime=new QueryWrapper<HktsCycleTime>();
            queryHktsCycleTime.lambda().eq(HktsCycleTime::getWorkShopId,curveVos.getWorkShop());
            HktsCycleTime hktsCycleTime = hktsCycleTimeMapper.selectOne(queryHktsCycleTime);
            hktsCycleTime.setCycleTime(toatalHour);
            hktsCycleTimeMapper.updateById(hktsCycleTime);

            CurveSettings ve = new CurveSettings();
            ve.setCurveId(curveVos.getCurveId());
            List<CurveSettings> curveSettingList = iCurveSettingsService.selectListforShelder(ve);
            for (int g = 0; g < curveSettingList.size(); g++) {
                curveSettingList.get(g).setCurrentSeconds(0);
                if (g == 0) {
                    curveSettingList.get(g).setCurrentNode("1");
                } else {
                    curveSettingList.get(g).setCurrentNode("0");
                }
            }
            iCurveSettingsService.updateBatchById(curveSettingList);
        }
       /* curve.setIsBegin(EnviromentCurveStateConstance.IS_BEGIN);
        curveMapper.updateById(curve);*/

        return ResultUtil.success("设置成功！");
    }
}
